Tornado Chart
A tornado chart is a common tool used to show the sensitivity of a result to changes in selected variables.
Properties
Series + Categories

Categories is an array of strings which are placed along the vertical axis of the chart.
Series is an array of objects describing each series of bars to make in the chart. Each series object expects the following configuration items:
name(the name of the series, as shown in the legend and tooltips)color(optional; the color to make the bars for this series)alignLeft(optional; whether the bars should be aligned to the left of the chart. The default is for bars to stack to the right)showInLegend(optional; whether the series should appear in the legend)data(An array of numbers which determine the size of each bar. One number should be supplied per category.)
For example, the chart shown in the above image was produced with the following configuration for Categories:
["Season 1", "Season 2", "Season 3", "Season 4"]
With the Series configuration being as follows:
[
{
"color": "#12A388",
"data": [4, 3, 2, 2],
"name": "Perth",
"alignLeft": true
},
{
"color": "green",
"data": [4, 3, 2, 1],
"name": "Melbourne"
},
{
"color": "#01CF86",
"data": [1, 2, 2, 1],
"name": "Sydney"
}
]
Title
(optional)
The title text to be displayed above the chart.
Note: It's recommended to choose to configure either one of Title or (LHS / RHS) Label, as having both active can be aesthetically busy.
Title Align
(Optional)
How the title should be aligned. Supported values:
leftcenterright
(LHS / RHS) Label
(optional)
Text to be displayed at the top of the chart on the left or right hand side, respectively.
(X / Y) Axis Title
(optional)
Text to be displayed on either axis.
Enable Tooltip
A flag that indicates whether a tooltip should appear when hovering over series on the chart.
Defaults to true
Tooltip Config
(optional)
Tooltip config accepts a ValueFormatSpec (see Appendix 1: Value Format Spec) object that will be applied to the y values in every series. For example, the following configuration:
{
"prefix": "$",
"suffix": " / unit",
"dp": 0
}
Will produce the following tooltip:

It should be noted that in the case where a tooltip is generated by an adaptor for a given series (such as when multi-column tooltips are generated from data, as shown in Generating Tooltips), the supplied Tooltip Configuration will be ignored for that series.
Shared Tooltip
A flag that indicates whether tooltips should show information for all series for a given category when hovered.
When true tooltips will appear like so:

When false only information for the hovered series will appear:

Defaults to true.
Side In Tooltip
A flag that indicates whether the name of each series in tooltips should include the label (see (LHS / RHS) Label) in brackets. This is useful for disambiguating series with the same name that appear on different sides of the tornado.
For example, consider the following chart which shows a breakdown of wins and losses of male and female participants in a series of games:

From a visualization standpoint, there's nothing inherently wrong with the way that the data is presented in the bars, however there is ambiguity in the tooltip concerning which row is associated with which bar.
By turning on the Side In Tooltip flag, the data is disambiguated by making use of the LHS and RHS labels in the tooltip:

Percentage Tooltips
A flag which, when enabled, will cause tooltips to show a bar's size as a percentage relative to the others in its group (defined by the direction the bar extends in the tornado, either left or right).

When this is set to true, the Tooltip Config property becomes irrelevant, since this only applies to the formatting of the y values of the series. Hence any configuration supplied to this property is ignored.
Defaults to false.
Show Legend
(optional)
A flag specifying whether the legend should be displayed in the chart.
Legend Orientation
(optional)
Defines the way in which legend items are laid out within the available space. Available options:
horizontalvertical
Defaults to horizontal
Horizontal Legend Position
(optional)
Defines where the legend sits along the horizontal plane. Available options:
leftcenterright
Defaults to center
Vertical Legend Position
(optional)
Defines where the legend sits along the vertical plane. Available options:
topmiddlebottom
Defaults to bottom
Y Axis Range
An tuple of length two that defines the range of the axis. For example, the following configuration will constrain an axis' values between 0 and 100:
[0, 100]
In the case where the creator wishes to specify only an upper or lower range on an axis, the string auto may be supplied for the bound whose value is inconsequential. For instance, an upper bound of 100 on an axis may be specified like so:
["auto", 100]
Show (X / Y) Axis
(optional)
Show X Axis and Show Y Axis are flags which control the visibility of the axes.
Defaults to true for both axes (i.e. visible)
(X / Y) Grid Lines
(Optional)
Flags that specify whether the faint gridlines distributed evenly behind the series are visible.
Default to true for both axes (i.e. visible)
Data Labels
Data labels are numeric annotations which are positioned either inside of, or next to bars. The Data Labels property accepts any of the following values, which determines what information to show in data labels:
none: No data labels will be displayed in the chart.inset-value: Display a data label inside of each bar, showing the absolute size of the bar.

inset-percentage: Display a data label inside of each bar, showing the proportion of the bar in its group (either LHS or RHS) as a percentage.

sum: Display a data label on the extremity of each group of bars, showing the sum of all values in the group.

Defaults to none.
Data Labels Multiplier
Large numbers are somewhat unsightly when shown in a data label. By selecting a multiplier, the value can be abbreviated (e.g. instead of displaying 10000000 in a data label, we can display 10M by choosing M as the multiplier).
Acceptable values:
auto: Choose a suitable multiplier based on the size of each number to be shown in a data label. This can result in a mix of formats for different labels if they differ enough in magnitude.k: Display values in thousandsm: Display values in millionsb: Display values in billionsNone: No multiplier, i.e. always show the full value.
Defaults to auto.
Data Labels Size
Determines the font size of the data labels shown in the chart. Acceptable values are small, medium, large, and huge.
Defaults to medium.
Adaptors
Table to Tornado Chart
The purpose of the Table to Tornado Chart adaptor is to dynamically produce series data (and optionally custom tooltips) for the Tornado chart from SDD.
As an example, we will be producing the following chart with the Table to Tornado Chart adaptor:

Table Data
This property should be linked to an SDD data source which will be used to generate bars and, optionally, custom tooltips.
Examples in this section assume Table Data has been linked to the following data set: Appendix 2: Tornado Chart SDD Dataset.
Filters
The applicable/available filters in this adaptor are more similar to those found elsewhere in Dais:
Available Filtersmay be linked to an object that maps filter names to filter specification objects. These objects containkey, avalueand a filtermethod.Applicable Filtersare a list of filter names in the object supplied toAvailable Filtersto apply.
The supported values that can be provided to method are:
"equal""contains""between""lt""gt""lte""gte"
An example configuration could be:
{
"ApplicableFilters": ["MyFilter", "MyOtherFilter"],
"AvailableFilters": {
"MyFilter": {
"key": "y",
"value": 50,
"method": "gte"
},
"MyOtherFilter": {
"key": "value",
"value": [90, 180],
"method": "between"
}
}
}
Series Config
Series Config accepts a list of objects that define:
- How the series should look visually
- How the series should pull data from the SDD data source to create the data for the bars and, optionally, custom tooltips.
A single series config object accepts the following configuration items:
name
The name of the series, as shown in legends and tooltips.
color
(optional)
The color used to fill the bars for this particular series.
showInLegend
(optional)
Whether the series should be shown in the legend.
alignLeft
(optional)
Whether the bars should be aligned to the left of the chart.
xDataKey,yDataKey
The column in the SDD data source from which x and y values for the bars should be sourced.
Note: xDataKey also defines the categories which are displayed in the chart, and thus can only be linked to string data. Since all bars are related to the same categories, every series config object must have the same xDataKey.
tooltipConfigMap
(optional)
A mapping between columns in the SDD and a ValueFormatSpec object describing how to display the values in the tooltip.
This is described in more detail in Generating Tooltips.
subFilterData
(optional)
An object that describes filters that should also be applied to the data, but for this particular series only.
This is described in more detail in Subfilters.
Subfilters
It is common for data to be filtered initially, then have all series be generated based on the filtered data. However, there are also use cases that involve performing extra filtering steps upon the already-filtered data, prior to creating a single series.
This functionality is made available through the concept of subfilters, with the subFilterData property.
As an example, consider data that has already been filtered according to the following Applicable and Available Filters:
{
"ApplicableFilters": ["MyFilter", "MyOtherFilter"],
"AvailableFilters": {
"MyFilter": {
"key": "y",
"value": 50,
"method": "gte"
},
"MyOtherFilter": {
"key": "value",
"value": [90, 180],
"method": "between"
}
}
}
Let's assume we want to make a bar series that uses these filters, but also is only associated with rows in the data having an enumValue of A and category of category-1 then a subFilterData object would be required:
// series config array
[
{
// configuration for a given series
"subFilterData": {
"subfilter1": {
"key": "enumValue",
"value": "A",
"method": "equals"
},
"subfilter2": {
"key": "category",
"value": "category-1",
"method": "equals"
}
}
}
]
Generating Tooltips
While there is functionality for defining how values in tooltips are presented that are applied at the chart level, it is also possible to create tooltips for a series that reference other columns in the SDD apart from those that were used to create the bar itself.
This can be achieved by providing a configuration object to the tooltipConfigMap property of a series in this adaptor.
To extend our example for this section, let's pretend that we want to show the following information in a tooltip:
- The number of participants who won (or lost) in a given trial
- The time of the fastest (in the case of winning) or slowest (in the case of losing) participant.

The above tooltip (for the Green Won series) was achieved by supplying the following configuration to tooltipConfigMap:
{
"nGreenWon": {
"name": "Green Won"
},
"fastestGreen": {
"name": "Fastest Participant",
"suffix": " minutes",
"dp": 2
}
}
Note: ValueFormatSpec does not typically include a name property - this is unique to the tooltip configuration for a given column. In this case, name is used to define the bold label shown per row.
In the case where name is not provided, the raw name of the column is used instead.
Sorting Config
Sorting the BarChart will change the order in which categories are laid out on the vertical axis, such that bars are sorted according to the directive provided to the Sorting property in the adaptor.
A sorting directive is a JSON object, described by the following TypeScript interface:
interface ITableSortDirective {
column: string
orderBy: 'asc' | 'desc'
}
The most common use case is to instruct the adaptor to sort the bars according to their values. In which case, the value for column would be the same as the yDataKey that was provided through Series Config.
Example
Let's assume we want to sort the chart by the number of green winners, in ascending order. The configuration supplied to Sorting would be:
{
"column": "nGreenWon",
"orderBy": "asc"
}
Producing the following sorted Tornado chart. Note the categories on the vertical axis are no longer in numbered order:

Complete Example Configuration
The entirety of the configuration for the example in this section is as follows:
Table Data: Linked to the data set in Appendix 2: Tornado Chart SDD Dataset.Series Config:
[
{
"name": "Red Won",
"yDataKey": "nRedWon",
"xDataKey": "category",
"color": "red",
"tooltipConfigMap": {
"nRedWon": {
"name": "Red Won"
},
"fastestRed": {
"name": "Fastest Participant",
"suffix": " minutes",
"dp": 2
}
}
},
{
"name": "Red Lost",
"yDataKey": "nRedLost",
"xDataKey": "category",
"alignLeft": true,
"color": "darkred",
"tooltipConfigMap": {
"nRedLost": {
"name": "Red Lost"
},
"slowestRed": {
"name": "Slowest Participant",
"suffix": " minutes",
"dp": 2
}
}
},
{
"name": "Green Won",
"yDataKey": "nGreenWon",
"xDataKey": "category",
"color": "green",
"tooltipConfigMap": {
"nGreenWon": {
"name": "Green Won"
},
"fastestGreen": {
"name": "Fastest Participant",
"suffix": " minutes",
"dp": 2
}
}
},
{
"name": "Green Lost",
"yDataKey": "nGreenLost",
"xDataKey": "category",
"alignLeft": true,
"color": "darkgreen",
"tooltipConfigMap": {
"nGreenLost": {
"name": "Green Lost"
},
"slowestGreen": {
"name": "Slowest Participant",
"suffix": " minutes",
"dp": 2
}
}
}
]
Appendix 1: Value Format Spec
A value format spec (ValueFormatSpec) is a configuration object used in a variety of use cases, which enables creators to customize the way in which numeric values are displayed. Example use cases include:
- Formatting numbers that appear in tooltips
- Formatting ticks on an axis
- Formatting data labels
The configuration items available in a value format spec are defined by the following snippet:
type ValueFormatSpec = {
prefix?: string
suffix?: string
multiplier?: 'm' | 'b' | 'k' | '1' | '%' | 'auto'
dp?: number
capitalize?: boolean
useLocale?: boolean
}
prefixandsuffixare optional strings to display before/after each value, respectively.dpis the number of decimal points to round to, when dealing with floating point values.useLocaledefines whether numbers should be formatted according to the user's locale (as per their browser):- e.g.
10,000,000instead of10000000.
- e.g.
multiplierallows a number to be abbreviated according to the following patterns:- e.g.
mis associated with millions:10000000becomes10M2345000becomes2.36M
- e.g.
%is associated with percentages:0.55becomes55%10becomes1,000%(assuminguseLocaleistrue)
autowill choose an appropriate multiplier on a per-value basis.
- e.g.
capitalizeis a flag that specifies whether the suffix made by a multiplier should be capitalized. Consider the value10000000(10 Million):capitalizebeingtruewill cause the value to be displayed as10Mcapitalizebeingfalse`` will cause the value to be displayed as10m`
All of the above properties are considered optional. If any are omitted, the following defaults are typically applied:
{
"prefix": "",
"suffix": "",
"multiplier": "auto",
"dp": 1,
"capitalize": true,
"useLocale": true
}
Appendix 2: Tornado Chart SDD Dataset
The following SDD data is used certain examples regarding configuring adaptors for the TornadoChart.
{
"data": [
{
"nRedWon": 33,
"nRedLost": 47,
"nGreenWon": 31,
"nGreenLost": 39,
"fastestRed": 57.755925638088414,
"fastestGreen": 61.46273044952447,
"slowestRed": 109.71157922390194,
"slowestGreen": 113.57270533412505,
"category": "Trial 1"
},
{
"nRedWon": 33,
"nRedLost": 49,
"nGreenWon": 40,
"nGreenLost": 42,
"fastestRed": 53.4342187075423,
"fastestGreen": 60.989873504155646,
"slowestRed": 119.60952678069299,
"slowestGreen": 101.75790640911518,
"category": "Trial 2"
},
{
"nRedWon": 33,
"nRedLost": 36,
"nGreenWon": 49,
"nGreenLost": 44,
"fastestRed": 58.26870359000892,
"fastestGreen": 53.92020103381866,
"slowestRed": 113.66881601504022,
"slowestGreen": 103.31060334537642,
"category": "Trial 3"
},
{
"nRedWon": 45,
"nRedLost": 46,
"nGreenWon": 32,
"nGreenLost": 41,
"fastestRed": 67.63888935365233,
"fastestGreen": 60.909681450177544,
"slowestRed": 100.00646016044885,
"slowestGreen": 106.24702486639615,
"category": "Trial 4"
},
{
"nRedWon": 45,
"nRedLost": 46,
"nGreenWon": 46,
"nGreenLost": 32,
"fastestRed": 62.04322769504997,
"fastestGreen": 52.08508633073058,
"slowestRed": 102.0101515071054,
"slowestGreen": 107.28004662477214,
"category": "Trial 5"
},
{
"nRedWon": 40,
"nRedLost": 48,
"nGreenWon": 32,
"nGreenLost": 32,
"fastestRed": 50.279981581141506,
"fastestGreen": 65.74282913509813,
"slowestRed": 111.58559249067864,
"slowestGreen": 117.77520905824542,
"category": "Trial 6"
},
{
"nRedWon": 38,
"nRedLost": 39,
"nGreenWon": 43,
"nGreenLost": 37,
"fastestRed": 65.2533631475538,
"fastestGreen": 51.29435260819479,
"slowestRed": 119.9135939296454,
"slowestGreen": 106.35284805798106,
"category": "Trial 7"
},
{
"nRedWon": 44,
"nRedLost": 37,
"nGreenWon": 35,
"nGreenLost": 37,
"fastestRed": 66.22079197036018,
"fastestGreen": 67.4868044566167,
"slowestRed": 101.52542842007227,
"slowestGreen": 110.72880194606434,
"category": "Trial 8"
},
{
"nRedWon": 36,
"nRedLost": 31,
"nGreenWon": 34,
"nGreenLost": 41,
"fastestRed": 66.12064712595553,
"fastestGreen": 54.866310123351695,
"slowestRed": 103.77393425725232,
"slowestGreen": 114.06612120661246,
"category": "Trial 9"
},
{
"nRedWon": 31,
"nRedLost": 44,
"nGreenWon": 41,
"nGreenLost": 33,
"fastestRed": 69.9199945300077,
"fastestGreen": 57.97103279415582,
"slowestRed": 105.63789095518564,
"slowestGreen": 116.32993350591354,
"category": "Trial 10"
},
{
"nRedWon": 48,
"nRedLost": 48,
"nGreenWon": 39,
"nGreenLost": 39,
"fastestRed": 56.41542507890163,
"fastestGreen": 55.76767501357167,
"slowestRed": 111.94500774277824,
"slowestGreen": 116.41822191474932,
"category": "Trial 11"
},
{
"nRedWon": 38,
"nRedLost": 49,
"nGreenWon": 34,
"nGreenLost": 33,
"fastestRed": 54.06821418045904,
"fastestGreen": 65.81559475409018,
"slowestRed": 115.43372840174843,
"slowestGreen": 107.12617659324602,
"category": "Trial 12"
}
],
"version": "1.0.0",
"sddFormat": "sdd/table/array-of-objects",
"validation": "enforced",
"definitions": {
"category": {
"kind": "string",
"optional": false
},
"nRedWon": {
"kind": "number",
"optional": false
},
"nRedLost": {
"kind": "number",
"optional": false
},
"nGreenWon": {
"kind": "number",
"optional": false
},
"nGreenLost": {
"kind": "number",
"optional": false
},
"fastestRed": {
"kind": "number",
"optional": false
},
"fastestGreen": {
"kind": "number",
"optional": false
},
"slowestRed": {
"kind": "number",
"optional": false
},
"slowestGreen": {
"kind": "number",
"optional": false
}
}
}